package com.easpeed.comon.utils

import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.BatteryManager
import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.easpeed.common.CommonConsts
import com.easpeed.comon.consts.ConstsApi
import com.easpeed.elevator.BuildConfig
import com.easpeed.user.bean.TcpBean
import com.example.permission.IRejectedCallback
import com.example.permission.IResultCallback
import com.example.permission.PermissionHelper
import java.io.File
import java.io.FileOutputStream
import java.io.IOException


/**
 * Created by bigyu on 2024/11/1 09:29
 * com.easpeed.user.utils
 */
fun ByteArray.bytesToHex(): String {
    return this.joinToString("") { String.format("%02X", it) }
}

@JvmOverloads
fun String.print(tag: String = "TAG") {
    //
    if (BuildConfig.DEBUG) {
        if (ConstsApi.isShowSocketLog) {
            com.bigyu.utils.Logger.e(tag, this)
        }
    }
}

fun String.hexToBytes(): ByteArray {
    return this.chunked(2).map { it.toInt(16).toByte() }.toByteArray()
}

fun String.hexStringToJson(): String {
    // 将每两个字符转换成一个字节
    val bytes = ByteArray(this.length / 2) {
        this.substring(it * 2, it * 2 + 2).toInt(16).toByte()
    }
    // 将字节数组转换为字符串
    return String(bytes)
}


fun String?.processEmpty(defaultStr: String? = ""): String? {
    if (this.isNullOrBlank()) {
        return defaultStr
    }
    return this
}


fun commonMainThread(block: () -> Unit) {
    Handler(Looper.getMainLooper()).post {
        block()
    }
}

fun TcpData.receiveSuccess(data: TcpBean): TcpData {
    this.code = TcpCode.SUCCESS
    this.msg = ""
    this.data = data
    return this
}

fun TcpData.reconnect(msg: String): TcpData {
    this.code = TcpCode.NEED_RECONNECT
    this.msg = ""
    return this
}

fun TcpData.connectSuccess(msg: String): TcpData {
    this.code = TcpCode.SUCCESS_SERVER
    this.msg = msg
    return this
}

fun TcpData.connectFailed(msg: String): TcpData {
    this.code = TcpCode.FAILED
    this.msg = msg
    return this
}


fun setViewsOnclickListener(vararg views: View?, block: (View) -> Unit) {
    views.forEach {
        it?.setOnClickListener {
            block(it)
        }
    }
}

/**
 * 显示隐藏控件
 *
 * @param isShow true 表显示
 */
fun View.setViewIsShow(isShow: Boolean) {
    visibility = if (isShow) View.VISIBLE else View.GONE
}

fun View?.setViewsOnclickListener(vararg views: Int, block: (View) -> Unit) {
    views.forEach {
        this?.findViewById<View>(it)?.setOnClickListener {
            block(it)
        }
    }
}

fun isUser(): Boolean {
    return CommonConsts.Type == "user"
}

fun createTcpPacket(deviceId: String, appType: Byte, command: ByteArray, data: ByteArray): ByteArray {
    // 帧头（3 字节）
    val header = byteArrayOf(0x7F, 0x7E, 0x7F)

    // 设备 ID (8 字节)，将 deviceId 填充或截断到 8 字节长度
    val deviceIdBytes = deviceId.padEnd(8).toByteArray().copyOf(8)

    // APP 类型（1 字节）
    val appTypeByte = byteArrayOf(appType)

    // 命令（2 字节）
    val commandBytes = command.copyOf(2)

    // 数据长度（4 字节）
    val dataLength = data.size
    val dataLengthBytes = byteArrayOf(
        (dataLength shr 24).toByte(), // 高 8 位
        (dataLength shr 16).toByte(), // 次高 8 位
        (dataLength shr 8).toByte(),  // 次低 8 位
        dataLength.toByte()          // 低 8 位
    )
    // 数据
    val dataBytes = data

    // 结束帧（3 字节）
    val footer = byteArrayOf(0x6F, 0x6E, 0x6F)

    // 组装所有部分
    val bytes = header + deviceIdBytes + appTypeByte + commandBytes + dataLengthBytes + dataBytes + footer


    "".print()
    "".print()
    "发送的原始数据包=>${bytes.joinToString(" ") { String.format("%02X", it) }}".print()
    return bytes
}

// 解析单个数据包的函数
@JvmOverloads
fun parseSinglePacket(packet: ByteArray, allMsg: Boolean = false): TcpBean? {
    if (packet.size < 21) return null  // 最小包长度检查

    // 查找帧头
    val headerIndex = packet.indexOfSequence(byteArrayOf(0x7F.toByte(), 0x7E.toByte(), 0x7F.toByte()))
    if (headerIndex == -1) return null  // 如果没有帧头，返回 null

    if (packet.size < headerIndex + 21) return null  // 包大小不够，返回 null

//        val dataLength = ((packet[headerIndex + 14].toInt() and 0xFF) shl 8) or (packet[headerIndex + 15].toInt() and 0xFF)
    val dataLength = ((packet[headerIndex + 14].toInt() and 0xFF) shl 24) or
            ((packet[headerIndex + 15].toInt() and 0xFF) shl 16) or
            ((packet[headerIndex + 16].toInt() and 0xFF) shl 8) or
            (packet[headerIndex + 17].toInt() and 0xFF)



    if (packet.size < headerIndex + 21 + dataLength) return null  // 数据不完整
    // 提取协议固定字段
    val deviceId = packet.copyOfRange(headerIndex + 3, headerIndex + 11).toString(Charsets.US_ASCII)
    val appType = packet[headerIndex + 11].toInt()
    val command = packet.copyOfRange(headerIndex + 12, headerIndex + 14)  // 2字节命令

    // 提取数据部分
    val data = packet.copyOfRange(headerIndex + 18, headerIndex + 18 + dataLength)

    // 检查结束帧
    val endFrame = packet.copyOfRange(headerIndex + 18 + dataLength, headerIndex + 21 + dataLength)
    if (!endFrame.contentEquals(byteArrayOf(0x6F.toByte(), 0x6E.toByte(), 0x6F.toByte()))) {
        return null  // 结束符不匹配，返回 null
    }

    // 处理数据，转换为 UTF-8 字符串
    val transData = String(data, Charsets.UTF_8)

    var isShow = allMsg
    // 返回封装后的 TcpBean
    val bean = TcpBean().apply {
        this.deviceId = deviceId
        this.appType = String.format("%02X", appType)
        this.command = command.bytesToHex()  // 命令转为十六进制表示
        this.dataLength = dataLength
        val start = System.currentTimeMillis()
        if (!command.contentEquals(SendCommand.commandDvsDataResponse) && !command.contentEquals(SendCommand.commandOTDRDataResponse)) {
            this.originalData = data.bytesToHex()
            isShow = true
            this.data = transData
        } else {
            this.dataBytes = data
//                this.dataBytes = data
        }
//            Logger.e("TAG", "parseSinglePacket:  ${System.currentTimeMillis() - start}")
        if (BuildConfig.DEBUG) {
            "解析数据包成功=============================".print()
            if (isShow) {
                "\t设备ID号: ${this.deviceId} \n\tAPP类型: ${String.format("%02X", appType)} \n\t命令：  ${this.command} \n\t数据长度 $dataLength \n\t转换后的数据 ${this.data} \n\t数据 ${originalData.hexStringToJson()}".print()
            } else {
                "\t设备ID号: ${this.deviceId} \n\tAPP类型: ${String.format("%02X", appType)} \n\t命令：  ${this.command} \n\t数据长度 $dataLength  end".print()
            }
//                Logger.e("TAG", "设备ID号: ${this.deviceId}")
//                Logger.e("TAG", "APP类型: ${String.format("%02X", appType)}")
//                Logger.e("TAG", "命令：  ${this.command}")
//                Logger.e("TAG", "数据长度 ${dataLength}")
//                Logger.e("TAG", "转换后的数据 ${data}")
//                Logger.e("TAG", "数据 ${originalData.hexStringToJson()}")
        }
    }

    return bean
}

// 辅助函数，用于查找字节序列
fun ByteArray.indexOfSequence(sequence: ByteArray): Int {
    for (i in indices) {
        if (i + sequence.size <= this.size && this.sliceArray(i until i + sequence.size).contentEquals(sequence)) {
            return i
        }
    }
    return -1
}

fun Bitmap?.transformFile(file: File): Boolean {
    if (this == null) {
        return false
    }
    return try {
        // 打开文件输出流
        val fileOutputStream = FileOutputStream(file)
        // 将 Bitmap 压缩为 JPEG 格式并写入文件流
        this.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
        fileOutputStream.flush()
        fileOutputStream.close()
        // 通知媒体库更新文件，便于图库应用能识别新文件
//        MediaScannerConnection.scanFile(context, arrayOf(file.toString()), null, null)
        true  // 返回保存的文件
    } catch (e: IOException) {
        e.printStackTrace()
        false
    }
}

fun File.transformBitmap(): Bitmap? {
    try {
        return BitmapFactory.decodeFile(this.absolutePath)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return null
}


fun FragmentActivity?.permissionRequest(permissions: ArrayList<String>, grantBlock: (() -> Unit)? = null, rejectBlock: (() -> Unit)? = null) {
    if (this == null) {
        rejectBlock?.invoke()
        return
    }
    PermissionHelper.with(this)
        .permissions(permissions)
        .explainAfterRejected(object : IRejectedCallback {
            override fun onRejected(process: IRejectedCallback.IRejectedProcess, rejectedPermissions: List<String>) {
                //当用户拒绝了某些权限后, 该回调先于IResultCallback#onResult回调，可以在这里弹出弹窗向用户解释被拒绝的权限对应用的必要性：
                //process：用户同意再次申请权限时，调用process的相应方法，继续权限申请流程
                //rejectedPermissions：被用户拒绝的权限
            }
        }).request(object : IResultCallback {
            override fun onResult(isAllGrant: Boolean, grantedPermissions: List<String>, rejectedPermissions: List<String>) {
                //授权结果回调
                if (isAllGrant) {
                    grantBlock?.invoke()
                } else {
                    rejectBlock?.invoke()
                }
            }
        })
}

fun Fragment?.permissionRequest(permissions: ArrayList<String>, grantBlock: (() -> Unit)? = null, rejectBlock: (() -> Unit)? = null) {
    if (this == null) {
        rejectBlock?.invoke()
        return
    }
    PermissionHelper.with(this)
        .permissions(permissions)
        .explainAfterRejected(object : IRejectedCallback {
            override fun onRejected(process: IRejectedCallback.IRejectedProcess, rejectedPermissions: List<String>) {
                //当用户拒绝了某些权限后, 该回调先于IResultCallback#onResult回调，可以在这里弹出弹窗向用户解释被拒绝的权限对应用的必要性：
                //process：用户同意再次申请权限时，调用process的相应方法，继续权限申请流程
                //rejectedPermissions：被用户拒绝的权限
            }
        }).request(object : IResultCallback {
            override fun onResult(isAllGrant: Boolean, grantedPermissions: List<String>, rejectedPermissions: List<String>) {
                //授权结果回调
                if (isAllGrant) {
                    grantBlock?.invoke()
                } else {
                    rejectBlock?.invoke()
                }
            }
        })
}
//fun createTcpPacketV2(deviceId: String, appType: String, command: String, data: String): ByteArray {
//    // 帧头（3 字节）
//    val header = byteArrayOf(0x7F, 0x7E, 0x7F).bytesToHex().hexToBytes()
//    // 设备 ID (8 字节)，将 deviceId 填充或截断到 8 字节长度
//    val deviceIdBytes = deviceId.padEnd(8).toByteArray().copyOf(8)
//
//    // APP 类型（1 字节）
//    val appTypeByte = appType.padEnd(1).hexToBytes()
//
//
//    // 命令（2 字节）
//    val commandBytes = command.hexToBytes()
//
//    // 数据长度（2 字节）
//    // 将字符串转换为字节数组
//    val dataBytes = data.toByteArray(Charsets.UTF_8)
//// 计算数据的字节长度
//    val dataLength = dataBytes.size
//// 将长度转换为字节数组（2字节表示）
//    val dataLengthBytes = byteArrayOf((dataLength shr 8).toByte(), dataLength.toByte())
//
//
//    // 结束帧（3 字节）
//    val footer =  byteArrayOf(0x6F, 0x6E, 0x6F).bytesToHex().hexToBytes()
//
//    // 组装所有部分
//    val bytes = header + deviceIdBytes + appTypeByte + commandBytes + dataLengthBytes + dataBytes + footer
//
//    "".print()
//    "".print()
//    "发送的原始数据包=>${bytes.joinToString(" ") { String.format("%02X", it) }}".print()
//    return bytes
//}

fun getBatteryLevel(context: Context): Int {
    // 获取电池信息的 Intent
    val ifilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
    val batteryStatus = context.registerReceiver(null, ifilter)

    if (batteryStatus != null) {
        // 获取当前电池电量和最大电量
        val level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        val scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1)

        if (level >= 0 && scale > 0) {
            // 计算电池百分比
            return ((level / scale.toFloat()) * 100).toInt()
        }
    }
    return 100 // 如果无法获取电量，则返回 -1
}